tp5+layui实现上传大文件介绍

(由于将文件进行了分段,所以在上传大文件时会发起大量的ajax请求,产生大量的并发,可能会导致页面再次崩溃。所以我才用错开请求的方式。减慢产生ajax请求的速度。)
接收完所有小文件后,调用后台方法将小文件进行合并
页面代码:
在第一次的基础上对所获取到的base64编码进行分割上传
服务端接收到后对数据进行解码,以编号进行命名
upload_tmp_dir //临时文件储存的路径
memory_limit 256M //单个PHP页面执行过程中可占用的最大内存,默认8M
max_execution_time 600 //单个PHP页面允许运行的最大时间
补充:413错误 如果服务器是nginx的话,需要更改配置nginx_conf 中的client_max_body_size 24M,设置接收客户端发送过来包的最大值。记得放在http里,重启服务器,用restart,不要用reload。
第一次尝试
<div class="layui-form-item"> <label class="layui-form-label">视频上传</label> <div class="layui-input-block layui-upload-video-btn"> <ul> <li class="img-upload"> <label></label> <input type="file" class="video-upload-file layui-upload-video-file-btn" name="file"/> <video width="320" height="240" controls style="display: none"> <source src=https://www.ym97.com/wenku/cssm"" type="video/mp4"> <source src=https://www.ym97.com/wenku/cssm"" type="video/ogg"> 您的浏览器不支持Video标签。 </video> <span style="display: none">X</span> <input type="hidden" class="video-link-id" name="video_link_id" value=https://www.ym97.com/wenku/cssm""> </li> <li>//视频上传会比较久(上传完会有提示)</li> </ul> </div> </div>js代码:
采用FileReader对象对文件进行读取
具体实现代码
后端框架:tp5
通过ajax将base64编码异步发送到服务端
测试结果失败,当文件过大时所编码的长度也越长,通过ajax异步提交参数的最大上线为8000个字节。
测试成功,测试上传了快4G的文件。
第三次尝试
前端框架:layui
实际开发
在第二次的基础上想着在读取文件获取编码的过程也进行分批读取来避免一次性读取过大的文件导致页面崩溃。
upload_max_filesize 20M //允许上传的文件最大值
通过更改上述的配置就可以调整允许文件上传的大小。(有的还需要调整服务器的一些配置)
通过ajax异步将文件的base64编码发送给服务端
接下来贴点代码
服务端接收数据进行解码和文件保存
max_input_time 600 //单个PHP页面接收数据所需的最大时间,默认60秒
通过FlieReader对象来读取文件快
post_max_size 22M //通过表单POST所能上传的大小
打开php.ini
file_uploads = on //是否允许通过HTTP上传文件的开关,默认开启
通过input file标签来选择文件
测试结果失败,当上传文件超过1G时,浏览器就崩溃了。应该是在读取文件时,文件过大,一次性读出返回base64编码过大,导致页面崩溃。
接着开始实现文件的分割上传。
第二次尝试
首先记录下更改文件上传大小的一些配置信息.
$('.video-upload-file').on('change',function(){ layer.msg('正在提交视频......'); //隐藏按钮,显示进度条 $('.layui-upload-video').hide(); $('.layui-progress-ads').show(); var loads_video = layer.load(2,{shade: [0.2, '#3a3535']}); //产生加载圈,禁止用户其他操作 var thisFile = $(this); var reader=new FileReader(); var file_size = this.files[0].size; //文件大小 var limit = 8388608; //每次读取文件的大小 // var limit = 1048000; //每次读取文件的大小 var up_count = Math.ceil(file_size/limit); //总上传次数 var type = this.files[0].type.substr(this.files[0].type.indexOf('/')+1); //文件类型 var success_num = 0; //用于存放上传成功的数据的id var check = 1; //防止多次合并 console.log('文件大小:'+this.files[0].size); console.log('文件类型:'+type); console.log('分割上传次数:'+up_count); //分段读取文件 readFile(this.files[0], 0, limit); function readFile(file, num, limit){ // console.log('第'+num+'次:'+num*limit); reader.readAsDataURL(file.slice(num*limit, (num+1)*limit)); reader.onload = function(e){ console.log(reader.result.length); console.log(reader.result); //异步base64的数据传输到服务器 ajax_way(reader.result, name, num+1, thisFile); if((num+1)*limit <= file_size){ readFile(file, num+1, limit); } } } function ajax_way(data,name,num, thisFile){ //避免一次性生成太多的请求 if(num+1 > 60){ // console.log('等待两秒'); sleep(6000); // console.log('等待结束'); } $.ajax({ url: "<?= url('admin/video/up_mfile');?>", type: "POST", data: {video:data,name:name,num:num}, // async:false, //是否采用同步,串行发送请求 success: function (data) { if(data.code == 1){ //上传成功,成功次数加一 success_num++; console.log(num+'完成'); console.log('已完成:'+success_num+'/'+up_count); //计算完成的百分比 var precentage = Math.ceil((success_num/up_count)*100); //更改进度条显示 $('.layui-progress-ads-btn').attr('lay-percent', precentage+'%'); $('.layui-progress-ads-btn').css('width', precentage+'%'); $('.layui-progress-text').html(precentage+'%'); //如果分割文件都上传了则调用接口合并文件 if(success_num == up_count && check == 1){ check = 0; success_num = 0; merge_mfile(name, up_count, thisFile, type); } } }, error:function(e){ console.log('出错了:'+num); //传输出错则重新上传 ajax_way(data, name, num, thisFile); } }); } //合并文件 function merge_mfile(name, count, thisFile, type){ $.ajax({ url:"<?= url('admin/video/merge_mfile');?>", data:{name:name, count:count, type:type}, type:"POST", success:function(data){ if (data.code==1){ layer.close(loads_video); layer.msg('视频提交成功'); thisFile.siblings('.video-link-id').val(data.data); }else{ layer.msg('视频提交异常请重新提交'); //显示按钮,隐藏进度条 $('.layui-upload-video').show(); $('.layui-progress-ads').hide(); //将进度条置零 $('.layui-progress-ads-btn').attr('lay-percent', '0%'); $('.layui-progress-ads-btn').css('width', '0%'); $('.layui-progress-text').html('0%'); //清空已选中的文件 var file = $(".layui-upload-video-file-btn"); file.after(file.clone().val("")); file.remove(); } } }) } function sleep(n) { //n表示的毫秒数 var start = new Date().getTime(); while (true) if (new Date().getTime() - start > n) break; } return false; });更多layui知识请关注layui使用教程栏目。
以上就是tp5+layui实现上传大文件介绍的详细内容,更多请关注聚合云库其它相关文章!
文件通过HTML的input标签的file来选择文件上传。通过H5新对象FileReader。就像字面上的意思一样FileRaeder对象就是一个读取本地文件的对象。FileReader对象可以将本地文件读取后以base64位的编码返回。(具体有关FileReader对象的使用,请自行百度,或者阅读以下博文,写的很具体。
服务端接收后对编码进行解码并保存到文件中。
这边就要使用到H5的file.slice()来对文件进行分块,从而实现分批读取分批上传。
将所获取的base64编码字符串分成几份并进行编号,在循环调用ajax进行发送
相关热词:
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://v30.fanwenzhu.com/jiaob/cssm/5258.shtml
相关文章
热门TAG
win10 ecshop 主机 阿里云 解决 配置 C# C++ 解析 SQL语句 命令 Go语言 方法 CSS3 HTML5 CSS win7 MSSQL 服务器配置 IIS7.5 IIS7 IIS6 IIS CentOS 7 Linux oracle数据库 oracle phpcms discuz discuz教程最新文章
-
其中border-left决定了底部直
时间:2021-01-23
-
当你自己回头来看你写的
时间:2021-01-23
-
④格式标签 粗体:b/b 斜
时间:2021-01-23
-
我们直接看代码: !DOCTY
时间:2021-01-23
-
这里就是吐槽的IE6!) 图
时间:2021-01-23
-
假设我们的HTML代码如下:
时间:2021-01-23
-
那么使用 CSS3 新增的选择
时间:2021-01-23
-
scaleGlassRectangle.y
时间:2021-01-23
热门文章
-
可以加我的HTML5前端交流群111645711 CSS源码
时间:2021-01-15
-
就可以对子元素进行 3D 变形操作了
时间:2021-01-12
-
用css让一个容器水平垂直
时间:2021-01-12
-
而没有设置高度
时间:2021-01-19
-
canvas与html5实现视频截图成果
时间:2021-01-19
-
所以通常不需要发送
时间:2021-01-19
-
我们尝试一下更新一下HTML结构
时间:2021-01-23
-
scaleGlassRectangle.y
时间:2021-01-23
-
HTML5生拖放实例分析
时间:2021-01-12
-
在全局:root{ }伪类中定义了一个 CSS 变量
时间:2021-01-21
